package com.yllt4cloud.ddauth.util.interceptor;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.util.Enumeration;

/**
 * @author HuangRiXuan 2018-07-17
 */
public class MybatisLogForm extends JFrame {

    public static void main(String[] args) {
        final MybatisLogForm mybatisLogForm = new MybatisLogForm();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                mybatisLogForm.setVisible(true);
            }
        });
    }

    private DefaultListModel<SqlCell> defModel = new DefaultListModel<SqlCell>();

    private Long maxUniqueCellId = 0l;

    public Long addCell(final String method, final String sqlId, final String sql) {
        ++maxUniqueCellId;
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                defModel.addElement(new SqlCell(method, maxUniqueCellId, defModel.size() + 1 + "-" + "[" + method + "] " + sqlId, sqlId, sql));
                int lastIndex = jList1.getModel().getSize() - 1;
                if (lastIndex >= 0) {
                    jList1.ensureIndexIsVisible(lastIndex);
                }
            }
        });
        return maxUniqueCellId;
    }

    public void addElapsedMillisToCell(final Long uniqueId, final BigDecimal elaspedTime) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Enumeration<SqlCell> sqlCellEnumeration = defModel.elements();
                while (sqlCellEnumeration.hasMoreElements()) {
                    SqlCell sqlCell = sqlCellEnumeration.nextElement();
                    if (uniqueId.equals(sqlCell.getId())) {
                        sqlCell.setSqlTitle(sqlCell.getSqlTitle() + String.format("    [%sms]", elaspedTime));
                        jList1.repaint();
                    }
                }
            }
        });
    }

    /**
     * Creates new form MybatisDebugForm
     */
    public MybatisLogForm() {
        initComponents();
        ToolTipManager.sharedInstance().setInitialDelay(0);
        jList1.setModel(defModel);
        jList1.setCellRenderer(new SqlCellRenderer());
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jSplitPane1 = new JSplitPane();
        jScrollPane1 = new JScrollPane();
        jList1 = new JList<SqlCell>() {
            public String getToolTipText(MouseEvent e) {
                int row = locationToIndex(e.getPoint());
                if (row != -1) {
                    SqlCell o = getModel().getElementAt(row);
                    if (o != null && getGraphics().getFontMetrics().stringWidth(o.getSqlTitle()) > jScrollPane1.getWidth())
                        return o.getSqlTitle();
                }
                return null;
            }

            public Point getToolTipLocation(MouseEvent e) {
                int row = locationToIndex(e.getPoint());
                if (row != -1) {
                    Rectangle r = getCellBounds(row, row);
                    if (r != null)
                        return new Point(r.x, r.y);
                }
                return null;
            }
        };
        jList1.setFixedCellHeight(22);
        jScrollPane2 = new JScrollPane();
        jTextArea1 = new JTextArea();
        jButton1 = new JButton();

        jTextArea1.setFont(new Font(jTextArea1.getFont().getName(), jTextArea1.getFont().getStyle(), jTextArea1.getFont().getSize() + 1));
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("可执行sql监视器");

        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jList1ValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jList1);

        jSplitPane1.setDividerLocation(366);
        jSplitPane1.setLeftComponent(jScrollPane1);
        jSplitPane1.setRightComponent(jScrollPane2);

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jTextArea1.setLineWrap(true);
        jTextArea1.setEditable(false);
        Caret caret = new DefaultCaret() {
            public void focusGained(FocusEvent e) {
                setVisible(true);
                setSelectionVisible(true);
            }
        };
        caret.setBlinkRate(UIManager.getInt("TextArea.caretBlinkRate"));
        jTextArea1.setCaret(caret);
        jScrollPane2.setViewportView(jTextArea1);

        jButton1.setText("清空sql");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGap(210, 210, 210)
                                .addComponent(jButton1)
                                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jSplitPane1, GroupLayout.DEFAULT_SIZE, 666, Short.MAX_VALUE)
                                .addContainerGap())
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addComponent(jSplitPane1, GroupLayout.DEFAULT_SIZE, 370, Short.MAX_VALUE)
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jButton1, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
                                .addContainerGap())
        );

        pack();
    }// </editor-fold>

    private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {
        if (jList1.getSelectedValue() != null) {
            jTextArea1.setText(jList1.getSelectedValue().getSql());
        } else {
            jTextArea1.setText(null);
        }
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        DefaultListModel listModel = (DefaultListModel) jList1.getModel();
        listModel.removeAllElements();
    }

    class SqlCell {

        private String method;
        private Long id;
        private String sqlTitle;
        private String sqlId;
        private String sql;

        public SqlCell(String method, Long id, String sqlTitle, String sqlId, String sql) {
            this.method = method;
            this.id = id;
            this.sqlTitle = sqlTitle;
            this.sqlId = sqlId;
            this.sql = sql;
        }

        public String getMethod() {
            return method;
        }

        public void setMethod(String method) {
            this.method = method;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getSqlTitle() {
            return sqlTitle;
        }

        public void setSqlTitle(String sqlTitle) {
            this.sqlTitle = sqlTitle;
        }

        public String getSqlId() {
            return sqlId;
        }

        public void setSqlId(String sqlId) {
            this.sqlId = sqlId;
        }

        public String getSql() {
            return sql;
        }

        public void setSql(String sql) {
            this.sql = sql;
        }
    }

    class SqlCellRenderer extends JLabel implements ListCellRenderer {

        private final Color SELECTION_COLOR = new Color(57, 105, 138);
        private final Color YELLOW_COLOR = new Color(72, 209, 204);
        //private final Color YELLOW_COLOR = new Color(151, 255, 255);
        private final Border border = new MatteBorder(0, 0, 1, 0, Color.BLACK);

        public SqlCellRenderer() {
            setOpaque(true);
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof SqlCell) {
                this.setBorder(border);
                SqlCell sqlCell = (SqlCell) value;
                setText(sqlCell.getSqlTitle());
                Color background;
                Color foreground;
                JList.DropLocation dropLocation = list.getDropLocation();
                if (dropLocation != null
                        && !dropLocation.isInsert()
                        && dropLocation.getIndex() == index) {
                    background = Color.BLUE;
                    foreground = Color.WHITE;
                } else if (isSelected) {
                    background = SELECTION_COLOR;
                    foreground = Color.WHITE;
                } else {
                    if ("update".equalsIgnoreCase(sqlCell.getMethod())
                            || "delete".equalsIgnoreCase(sqlCell.getMethod())
                            || "insert".equalsIgnoreCase(sqlCell.getMethod())) {
                        background = Color.WHITE;
                        foreground = Color.RED;
                    } else {
                        background = Color.WHITE;
                        foreground = Color.BLACK;
                    }
                }
                ;
                setBackground(background);
                setForeground(foreground);
            }
            return this;
        }

    }

    // Variables declaration - do not modify
    private JButton jButton1;
    private JList<SqlCell> jList1;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JSplitPane jSplitPane1;
    private JTextArea jTextArea1;
    // End of variables declaration
}

